#include "stdafx.h"
#include "ConfigLoaderXml.h"
#include "tinyxml.h"
#include "Log\Log.h"

namespace woe
{

	ConfigLoaderXml::ConfigLoaderXml()
	{

	}

	ConfigLoaderXml::~ConfigLoaderXml()
	{

	}

	bool ConfigLoaderXml::DoLoad(const std::string& strXmlName, IConfigOperator* config)
	{
		TiXmlDocument* doc = new TiXmlDocument( strXmlName );
		if ( !doc )
		{
			LOG_ERROR_V("Failed to (ConfigLoaderXml::DoLoad)open xml file %s\n",strXmlName.c_str());
			return false;
		}
		if ( !doc->LoadFile() )
		{
			if (doc->Error() == true)
			{
				LOG_ERROR_V("Failed to (ConfigLoaderXml::DoLoad)load xml file %s\n",strXmlName.c_str());
				LOG_ERROR(doc->ErrorDesc());
			}
			else
			{
				LOG_ERROR_V("Failed to (ConfigLoaderXml::DoLoad)load xml file %s\n",strXmlName.c_str());
			}
			delete doc;
			return false;
		}
		TiXmlNode* RootNode = doc ->RootElement();
		if ( !RootNode )
		{
			LOG_ERROR("Failed to (ConfigLoaderXml::DoLoad)get rootnode\n");
			delete doc;
			return false;
		}
		FindNode( RootNode,config );
		delete doc;
		return true;
	}

	bool ConfigLoaderXml::DoSetXmlString(const std::string& strXmlstring, IConfigOperator* config)
	{
		TiXmlDocument* doc = new TiXmlDocument();
		if ( !doc )
		{
			LOG_ERROR("Failed to (ConfigLoaderXml::DoSetXmlString)open xml file\n");
			return false;
		}
		if(!doc->Parse(strXmlstring.c_str()))
		{
			LOG_ERROR_V("Failed to (SetXmlString), str : %s\n", strXmlstring.c_str());
			delete doc;
			return false;
		}

		TiXmlNode* RootNode = doc ->RootElement();
		if ( !RootNode )
		{
			LOG_ERROR("Failed to (ConfigLoaderXml::DoSetXmlString)get rootnode\n");
			delete doc;
			return false;
		}
		FindNode( RootNode,config );
		delete doc;
		return true;
	}

	void ConfigLoaderXml::FindNode( TiXmlNode* node, IConfigOperator* config )
	{
		if ( !config || !node )
		{
			LOG_DEBUG("Failed to , ConfigLoaderXml::FindNode, the param  is NULL\n");
			return ;
		}
		std::string strKey("NULL"), strValue("NULL");
		for (  TiXmlNode* child = node->FirstChild(); child; child = child->NextSibling() )
		{
			if ( child->Type() == TiXmlNode::TINYXML_ELEMENT )
			{
				strKey = child->Value();

				for ( TiXmlNode* parent = child->Parent(); parent; parent = parent->Parent() )
				{
					if ( parent->Type() != TiXmlNode::TINYXML_DOCUMENT )
						strKey = std::string(parent->Value())+"."+strKey;
				}

				if ( child->NoChildren() || child->FirstChild()->Type() == TiXmlNode::TINYXML_TEXT )
				{
					//<a>tmpNode</a>, tmpNode is a's child
					TiXmlNode* tmpNode = child->FirstChild();
					if (tmpNode)
					{
						strValue = tmpNode->Value();
						//stringmap.insert(std::map<std::string,std::string>::value_type(strKey,strValue));
						config->Set(strKey,strValue);
					}
				}

				TiXmlElement* tmpElement = (TiXmlElement*)child;
				for ( TiXmlAttribute* attr = tmpElement->FirstAttribute(); attr; attr = attr->Next() )
				{
					std::string strTmp(strKey);
					strValue = attr->Value();
					strTmp = strTmp+"."+std::string(attr->Name());
					//stringmap.insert(std::map<std::string,std::string>::value_type(strTmp,strValue));
					config->Set(strTmp,strValue);
				}

				FindNode( child,config );
			}
		}
	}
}